﻿using Cherry.Agile.Data.DataAccess;
using Cherry.Agile.Enterprise.Entity;
//using Cherry.Agile.Enterprise.Entity.Enum;
//using Cherry.Agile.Enterprise.Repository;
using Cherry.Agile.Enterprise.Services.Interface;
using Cherry.Agile.Framework.Cache;
using Cherry.Agile.Security;
using Cherry.Agile.ServiceModel.Interceptor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cherry.Agile.Enterprise.Services
{

    [ServiceInterceptor(IsBidirectional = false)]
    public class AuthorizationService : IAuthorizationService
    {

        //const string cacheName = "distributed";
        //static Lazy<ICache> _lazyCache = new Lazy<ICache>(() => CacheManager.GetCache(cacheName));

        //#region cache
        //static string GetKey(string roleName)
        //{
        //    if (string.IsNullOrEmpty(roleName))
        //        throw new ArgumentNullException("rolename");
        //    return roleName + "@roles";
        //}

        //internal static void AddRoleToCache(string roleName, Role role)
        //{
        //    System.Diagnostics.Trace.WriteLine("AuthorizationService\t push role into cache:" + roleName);
        //    _lazyCache.Value.Add(GetKey(roleName), role);
        //}

        //internal static void RemoveRoleFromCache(string roleName)
        //{
        //    System.Diagnostics.Trace.WriteLine("AuthorizationService\t remove role from cache:" + roleName);
        //    _lazyCache.Value.Remove(GetKey(roleName));
        //}

        //internal static Role GetRoleFromCache(string roleName)
        //{
        //    var val = _lazyCache.Value.GetData<Role>(GetKey(roleName));
        //    if (val != null)
        //        System.Diagnostics.Trace.WriteLine("AuthorizationService\t get role from cache:" + roleName);
        //    return val;
        //}
        //#endregion

        //public Cherry.Agile.Security.User GetUser(Cherry.Agile.Security.AccountTicket ticket)
        //{
          
        //    Cherry.Agile.Security.User result;
        //    using (var scope = new DbConnectionScope(Unity.AGILEDATABASE))
        //    {
        //        //if (ticket.Type == (int)StaffOrUserEnum.Staff)
        //            result = GetStaff(ticket);
        //        //else
        //            result = GetPatient(ticket);
        //    }

        //    if (result != null)
        //    {
        //        ticket.Id = result.ID;
        //        result.Organizations = GetUserOrgs(ticket);
        //        result.Roles = GetUserRoles(ticket);
        //    }
        //    return result;
        //}

        //private Cherry.Agile.Security.User GetStaff(Cherry.Agile.Security.AccountTicket ticket)
        //{
        //    //using (var repository = new EmployeeRepository())
        //    //{
        //    //    var q = repository.CreateQuery<EmployeeInfo>().Where(c => c.EmployeeAccount == ticket.Identity && c.Invalid == 0);

        //    //    var user = q.FirstOrDefault();
        //    //    if (user != null)
        //    //    {
        //    //        return new Cherry.Agile.Security.User()
        //    //        {
        //    //            ID = user.EmployeeID,
        //    //            Identity = user.EmployeeAccount,
        //    //            FullName = user.EmployeeName,
        //    //            UserType = (int)EmployeeOrUserEnum.Employee,
        //    //            Status = user.IsEnable,
        //    //            Password = user.Password
        //    //        };
        //    //    }
        //    //    return null;
        //    //}
        //    return null;
        //}

        //private Cherry.Agile.Security.User GetPatient(Cherry.Agile.Security.AccountTicket ticket)
        //{
        //    //using (var repository = new PatientRepository())
        //    //{
        //    //    //var user = repository.GetBy<PatientInfo>(c => (c.CredNO == ticket.Identity
        //    //    //                    || c.MemberID == ticket.Identity) && c.Invalid == 0);
        //    //    var user = repository.GetBy<PatientInfo>(c => c.PatientAccount == ticket.Identity && c.Invalid == 0);
        //    //    if (user != null)
        //    //    {
        //    //        return new Cherry.Agile.Security.User()
        //    //        {
        //    //            ID = user.PatientID,
        //    //            Identity = ticket.Identity,
        //    //            FullName = user.PatientName,
        //    //            UserType = (int)DoctorOrPatientEnum.Patient,
        //    //            Tag = user.MemberID,
        //    //            Status = 1, //会员永远可以登录  // user.IsEnable,
        //    //            Password = user.Password

        //    //        };
        //    //    }
        //        return null;
        //    //}
        //}

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="tiket"></param>
        ///// <returns></returns>
        //public Cherry.Agile.Security.Role[] GetUserRoles(Cherry.Agile.Security.AccountTicket ticket)
        //{

        //    //using (var scope = new DbConnectionScope(Unity.AGILEDATABASE))
        //    //{
        //    //    return GetRoleFunctions(ticket.Id, (EmployeeOrUserEnum)ticket.Type).ToArray();
        //    //}
        //    return null;

        //}

        //static Lazy<Dictionary<int, Cherry.Agile.Security.Permission>> _lazyPermission = new Lazy<Dictionary<int, Permission>>(
        //    () =>
        //    {
        //        using (var scope = new DbConnectionScope(Unity.AGILEDATABASE))
        //        {
        //            //using (var fo = new FunctionRepository())
        //            //{
        //            //    var functions = fo.GetFunctionListCache();
        //            //    return functions.Select(f => new Cherry.Agile.Security.Permission() { ID = f.FuncID, Name = f.FuncName, Code = f.FuncCode })
        //            //        .ToDictionary(d => d.ID);
        //            //}
        //            return null;
        //        }
        //    });



        //private IEnumerable<Role> GetRolesByNames(string[] rolesNames)
        //{
        //    //using (var repository = new RoleFuncInfoRepository())
        //    //{
        //    //    var rs = repository.CreateQuery<RoleFuncInfo>();
        //    //    var ri = repository.CreateQuery<RoleInfo>();

        //    //    var query = from c in rs
        //    //                join r in ri on c.RoleID equals r.RoleID
        //    //                where rolesNames.Contains(r.RoleName)
        //    //                orderby r.RoleName
        //    //                group c.FuncID by r.RoleName into g
        //    //                select g;

        //    //    foreach (var kv in query.ToList())
        //    //    {
        //    //        var role = new Role { Name = kv.Key, Code = kv.Key };
        //    //        var fun = _lazyPermission.Value.Where(c => kv.Contains(c.Key)).Select(c => c.Value).ToArray(); //functions.Where(c => kv.Contains(c.FuncID)).Select(f => new Cherry.Agile.Security.Permission() { ID = f.FuncID, Name = f.FuncName, Code = f.FuncCode }).ToArray();
        //    //        role.Permissions = fun;
        //    //        yield return (role);
        //    //    }
        //    //}
        //    return null;
        //}

        ////private List<Role> GetRoleFunctions(int id, EmployeeOrUserEnum type)
        ////{
        ////    List<Role> roles = new List<Role>();
        ////    string[] roleNames;
        ////    using (var repository = new RoleFuncInfoRepository())
        ////    {
        ////        if (type == EmployeeOrUserEnum.Employee)
        ////        {

        ////            var ri = repository.CreateQuery<RoleInfo>();
        ////            var rd = repository.CreateQuery<RoleEmpInfo>();
        ////            var query = from r in ri
        ////                        join d in rd on r.RoleID equals d.RoleID
        ////                        where d.EmpID == id
        ////                        select r.RoleName;
        ////            roleNames = query.Distinct().ToArray();
        ////        }
        ////        else
        ////        {
        ////            var ri = repository.CreateQuery<RoleInfo>();
        ////            var rd = repository.CreateQuery<RoleCustInfo>();
        ////            var query = from r in ri
        ////                        join d in rd on r.RoleID equals d.RoleID
        ////                        where d.CustID == id
        ////                        select r.RoleName;

        ////            roleNames = query.Distinct().ToArray();
        ////        }
        ////    }

        ////    return GetRole(roleNames);


        ////}

        //private List<Role> GetRole(string[] roleNames)
        //{
        //    List<Role> roles = new List<Role>();
        //    List<string> names = new List<string>();
        //    foreach (var item in roleNames)
        //    {
        //        var role = GetRoleFromCache(item);
        //        if (role != null)
        //            roles.Add(role);
        //        else
        //            names.Add(item);
        //    }
        //    if (names.Count > 0)
        //    {
        //        foreach (var role in GetRolesByNames(names.ToArray()))
        //        {
        //            roles.Add(role);
        //            AddRoleToCache(role.Name, role);
        //        }
        //    }
        //    return roles;
        //}

        //public Cherry.Agile.Security.Organization[] GetUserOrgs(Cherry.Agile.Security.AccountTicket ticket)
        //{
        //    //using (var scope = new DbConnectionScope(Unity.AGILEDATABASE))
        //    //{
        //    //    List<OrganizationInfo> lst = new List<OrganizationInfo>();
        //    //    using (var repository = new OrganizationRepository())
        //    //    {
        //    //        if (ticket.Type == (int)EmployeeOrUserEnum.Employee)
        //    //        {
        //    //            //lst = repository.GetDoctorOrgs(ticket.Id);
        //    //            lst = repository.GetOrganizationInfoByEmployeeID(ticket.Id);
        //    //        }
        //    //        //else
        //    //        //{
        //    //        //    MemberServiceInfo info;
        //    //        //    using (var rep = new MemberServiceRepository())
        //    //        //    {
        //    //        //        info = rep.GetLatestMemberServiceByPatientID(ticket.Id);
        //    //        //    }
        //    //        //    OrganizationInfo org = repository.GetOrganizationInfoByID(info.OrgID);
        //    //        //    lst = new List<OrganizationInfo>();
        //    //        //    lst.Add(org);
        //    //        //}
        //    //    }

        //    //    return lst.Select(c => new Cherry.Agile.Security.Organization()
        //    //    {
        //    //        Id = c.OrgID,
        //    //        Name = c.OrgName,
        //    //        Path = c.OrgPath,
        //    //        ParentId = c.ParentOrgID,
        //    //        Type = c.OrgType,
        //    //        Kind = c.OrgKind,
        //    //        Logofile = c.Logofile,
        //    //        MembersSiteLogo = c.MembersSiteLogo

        //    //    }).OrderBy(o => o.Path).ToArray();
        //    //}
        //    return null;
        //}
        public User GetUser(AccountTicket ticket)
        {
            return null;
        }

        public Role[] GetUserRoles(AccountTicket tiket)
        {
            throw new NotImplementedException();
        }

        public Organization[] GetUserOrgs(AccountTicket tiket)
        {
            throw new NotImplementedException();
        }
    }
}
